package root.electronclass.electronclass.grade.widget

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import root.electronclass.electronclass.R
import java.text.DecimalFormat
import kotlin.random.Random
import androidx.core.content.withStyledAttributes

/**
 * 柱图表
 * @author Lokiy
 * @date 2023/3/25 16:23
 */
open class PillarChartView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    View(context, attrs, defStyleAttr) {
    private val mPaint = Paint()
    private val mLinePaint = Paint()

    val data: MutableList<LineChartData> = mutableListOf()
    private val path = Path()

    //横着的有多少条线 不包含X轴
    var horizontalLineCount = 7
    private var verticalSpace = 0f
    private var horizontalSpace = 0f
    private val df = DecimalFormat("0.#")
    var yFormatter: (index: Int) -> String = { it.toString() }

    private var isDrawPoint = false

    init {
        var lineWidth = 0f
        context.withStyledAttributes(attrs, R.styleable.LineChartView) {
            horizontalLineCount = getInt(R.styleable.LineChartView_horizontalLineCount, horizontalLineCount)
            isDrawPoint = getBoolean(R.styleable.LineChartView_isDrawPoint, isDrawPoint)
            verticalSpace = getDimension(R.styleable.LineChartView_verticalSpace, dp2px(30f))
            horizontalSpace = getDimension(R.styleable.LineChartView_horizontalSpace, dp2px(30f))
            lineWidth = getDimension(R.styleable.LineChartView_lineWidth, dp2px(2f))
        }
        mPaint.color = 0xFF000000.toInt()
        mPaint.strokeWidth = dp2px(1f)
        mPaint.textSize = dp2px(12f)
        mPaint.style = Paint.Style.FILL
        mPaint.isAntiAlias = true

        //折线画笔
        mLinePaint.strokeWidth = lineWidth
        mLinePaint.style = Paint.Style.STROKE
        mLinePaint.isAntiAlias = true
        if (isInEditMode) {
            repeat(2) {
                val line = mutableListOf<Float>()
                repeat(7) {
                    if (data.isEmpty()) {
                        line.add(Random.nextInt(20) + 20f)
                    } else {
                        line.add(40f - data[0].values[it])
                    }
                }
                val item = LineChartData(Color.rgb(Random.nextInt(255), Random.nextInt(255), Random.nextInt(255)), line)
                data += item
            }
        }
    }
    override fun onDraw(canvas: Canvas) {
        if (data.isEmpty()) return

        val chartWidth = width.toFloat() - horizontalSpace * 2
        val chartHeight = height.toFloat() - verticalSpace * 2

        val maxSize = data[0].values.size
        // 计算每个X的总和，决定柱子高度比例
        val sumList = (0 until maxSize).map { index ->
            data.sumOf { it.values[index].toDouble() }.toFloat()
        }
        val maxCount = (sumList.maxOrNull() ?: 0f).takeIf { it > 0f } ?: 30f

        val itemWidth = chartWidth / maxSize * 0.6f // 柱子宽度
        val itemSpace = chartWidth / maxSize

        for (i in 0 until maxSize) {
            var bottom = chartHeight + verticalSpace
            for (j in data.indices) {
                val value = data[j].values[i]
                val barHeight = chartHeight * (value / maxCount)
                val left = horizontalSpace + i * itemSpace + (itemSpace - itemWidth) / 2
                val right = left + itemWidth
                val top = bottom - barHeight

                mLinePaint.color = data[j].color
                mLinePaint.style = Paint.Style.FILL
                canvas.drawRect(left, top, right, bottom, mLinePaint)

                // 绘制数值
                mPaint.color = Color.WHITE
                mPaint.textSize = dp2px(12f)
                mPaint.textAlign = Paint.Align.CENTER
                val text = value.toInt().toString()
                val textY = top + (barHeight / 2) + mPaint.textSize / 3
                canvas.drawText(text, (left + right) / 2, textY, mPaint)

                bottom = top
            }
        }

        // 绘制X轴文字
        val textY = chartHeight + verticalSpace + dp2px(18f)
        mPaint.color = 0xFF000000.toInt()
        mPaint.textAlign = Paint.Align.CENTER
        for (i in 0 until maxSize) {
            val x = horizontalSpace + i * itemSpace + itemSpace / 2
            val text = yFormatter.invoke(i)
            canvas.drawText(text, x, textY, mPaint)
        }
    }

    private fun dp2px(value: Float) = value

    data class LineChartData(
        val color: Int,
        val values: List<Float>,
    )


}